package com.sale.goods.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sale.common.core.constant.CacheNames;
import com.sale.common.core.exception.GlobalException;
import com.sale.common.mybatis.core.page.PageQuery;
import com.sale.common.mybatis.core.page.TableDataInfo;
import com.sale.common.redis.utils.CacheUtils;
import com.sale.common.satoken.utils.LoginHelper;
import com.sale.goods.domain.GoodsCostAdjustment;
import com.sale.goods.domain.dto.CostAdjustmentDto;
import com.sale.goods.domain.dto.GoodsCostAdjustmentDto;
import com.sale.goods.domain.dto.GoodsCostAdjustmentViewDto;
import com.sale.goods.domain.vo.ExamineVo;
import com.sale.goods.domain.vo.GoodsCostAdjustmentAddVo;
import com.sale.goods.domain.vo.GoodsCostAdjustmentVo;
import com.sale.goods.mapper.GoodsCostAdjustmentMapper;
import com.sale.goods.service.GoodsCostAdjustmentService;
import com.sale.storage.api.RemoteWarehouseNameService;
import com.sale.storage.api.RemoteWipService;
import com.sale.storage.api.dto.UpdateWipByAdjustmentVo;
import com.sale.storage.api.dto.WipCompletionMessageDto;
import com.sale.system.api.RemoteMaterialService;
import com.sale.system.api.RemoteReviewService;
import com.sale.system.api.RemoteUnitService;
import com.sale.system.api.domain.SysAuxiliary;
import com.sale.system.api.domain.SysDictData;
import com.sale.system.api.domain.dto.FinishAndRawDto;
import com.sale.system.api.domain.vo.SysAuditHistoryVo;
import com.sale.system.api.model.MaterialUnitDto;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 成本调整实现层
 */
@RequiredArgsConstructor
@Service
public class GoodsCostAdjustmentServiceImpl implements GoodsCostAdjustmentService {

    private final GoodsCostAdjustmentMapper goodsCostAdjustmentMapper;

    @DubboReference
    RemoteMaterialService remoteMaterialService;

    @DubboReference
    RemoteUnitService remoteUnitService;

    @DubboReference
    RemoteWarehouseNameService remoteWarehouseNameService;

    @DubboReference
    RemoteWipService remoteWipService;

    @DubboReference
    RemoteReviewService remoteReviewService;


    /**
     * 成本调整分页列表
     */
    @Override
    public TableDataInfo<GoodsCostAdjustmentDto> getCostAdjustmentList(GoodsCostAdjustmentVo goodsCostAdjustmentVo, PageQuery pageQuery) {
        Page<GoodsCostAdjustmentDto> list = goodsCostAdjustmentMapper.getCostAdjustmentList(goodsCostAdjustmentVo, pageQuery.build());
        List<GoodsCostAdjustmentDto> records = list.getRecords();
        //状态
        List<SysDictData> statusArray = CacheUtils.get(CacheNames.SYS_DICT, "goods_cost_adjustment_status");
        Map<String, String> statusMap = statusArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        for (GoodsCostAdjustmentDto entity : records) {
            //调整方式
            if ("1".equals(entity.getAdjustmentMode())) {
                entity.setAdjustmentModeDict("物料调整");
            }else {
                entity.setAdjustmentModeDict("单据调整");
            }
            //单据状态
            entity.setStatusDict(statusMap.get(entity.getStatus()));
        }
        return TableDataInfo.build(list);
    }

    /**
     * 成本调整新增
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean costAdjustmentAdd(GoodsCostAdjustmentAddVo goodsCostAdjustmentAddVo) {
        List<GoodsCostAdjustmentVo> addList = goodsCostAdjustmentAddVo.getAddList();
        if (addList.size() < 1) {
            throw new GlobalException("至少新增一条数据");
        }
        List<GoodsCostAdjustment> result = new ArrayList<>();
        for (GoodsCostAdjustmentVo entity : addList) {
            GoodsCostAdjustment goodsCostAdjustment = new GoodsCostAdjustment();
            //物料调整
            if ("1".equals(goodsCostAdjustmentAddVo.getAdjustmentMode())) {
                goodsCostAdjustment.setAdjustmentMode(goodsCostAdjustmentAddVo.getAdjustmentMode())
                    .setOperatorTime(goodsCostAdjustmentAddVo.getOperatorTime())
                    .setAdjustmentAmount(entity.getAdjustmentAmount())
                    .setWarehouse(entity.getWarehouse())
                    .setRemark(entity.getRemark())
                    .setOutRemark(goodsCostAdjustmentAddVo.getOutRemark())
                    .setMaterialCode(entity.getMaterialCode())
                    .setCreateTime(new Date())
                    .setOperatorBy(LoginHelper.getUsername())
                    .setStatus(1);
            } else {
                //单据调整
                goodsCostAdjustment.setDocumentNumber(entity.getDocumentNumber())
                    .setAdjustmentMode(goodsCostAdjustmentAddVo.getAdjustmentMode())
                    .setOperatorTime(goodsCostAdjustmentAddVo.getOperatorTime())
                    .setAdjustmentAmount(entity.getAdjustmentAmount())
                    .setWarehouse(entity.getWarehouse())
                    .setOutRemark(goodsCostAdjustmentAddVo.getOutRemark())
                    .setRemark(entity.getRemark())
                    .setMaterialCode(entity.getMaterialCode())
                    .setCreateTime(new Date())
                    .setOperatorBy(LoginHelper.getUsername())
                    .setStatus(1);
            }
            result.add(goodsCostAdjustment);
        }
        return goodsCostAdjustmentMapper.insertBatch(result);
    }

    /**
     * 成本调整修改
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean costAdjustmentUpdate(GoodsCostAdjustmentAddVo goodsCostAdjustmentAddVo) {
        GoodsCostAdjustment goodsCostAdjustment = goodsCostAdjustmentMapper.selectById(goodsCostAdjustmentAddVo.getId());
        if (goodsCostAdjustment.getStatus() != 1 && goodsCostAdjustment.getStatus() != 4) {
            throw new GlobalException("只能对”待提交”和”未通过”状态的单据进行修改");
        }
        List<GoodsCostAdjustmentVo> addList = goodsCostAdjustmentAddVo.getAddList();

        for (GoodsCostAdjustmentVo entity : addList) {
            goodsCostAdjustment.setDocumentNumber(entity.getDocumentNumber())
                .setAdjustmentMode(goodsCostAdjustmentAddVo.getAdjustmentMode())
                .setOperatorTime(goodsCostAdjustmentAddVo.getOperatorTime())
                .setAdjustmentAmount(entity.getAdjustmentAmount())
                .setWarehouse(entity.getWarehouse())
                .setOutRemark(goodsCostAdjustmentAddVo.getOutRemark())
                .setRemark(entity.getRemark())
                .setMaterialCode(entity.getMaterialCode())
                .setCreateTime(new Date())
                .setOperatorBy(LoginHelper.getUsername())
                .setStatus(1);
        }
        //调用审核
        if (goodsCostAdjustment.getStatus() == 4) {
            SysAuditHistoryVo sysAuditHistoryVo = new SysAuditHistoryVo();
            String perms = "finance:adjustment:examine";
            String auditDoc = goodsCostAdjustment.getId().toString();
            sysAuditHistoryVo.setAuditDoc(auditDoc);
            sysAuditHistoryVo.setPerms(perms);
            int i = remoteReviewService.editHistory(sysAuditHistoryVo);
            if (i > 0) {
                goodsCostAdjustment.setStatus(1);
//                //修改审核代办状态为已处理
//                remoteWorkbenchMessageService.updateStatus(3, purchaseOrder.getPurchaseOrderNo(), "采购订单");
                return goodsCostAdjustmentMapper.updateById(goodsCostAdjustment) > 0;
            } else {
                return false;
            }
        }
        return goodsCostAdjustmentMapper.updateById(goodsCostAdjustment) > 0;
    }

    /**
     * 成本调整查看
     */
    @Override
    public GoodsCostAdjustmentViewDto costAdjustmentGetView(Long id) {
        GoodsCostAdjustment goodsCostAdjustment = goodsCostAdjustmentMapper.selectById(id);
        GoodsCostAdjustmentViewDto goodsCostAdjustmentViewDto = new GoodsCostAdjustmentViewDto();
        //开单时间
        goodsCostAdjustmentViewDto.setOperatorTime(goodsCostAdjustment.getOperatorTime());
        goodsCostAdjustmentViewDto.setId(goodsCostAdjustment.getId());

        List<CostAdjustmentDto> result = new ArrayList<>();
        CostAdjustmentDto costAdjustmentDto = new CostAdjustmentDto();
        if ("1".equals(goodsCostAdjustment.getAdjustmentMode())) {
            //物料调整
            goodsCostAdjustmentViewDto.setAdjustmentMode("物料调整");
            //根据编码获取物料相关信息
            FinishAndRawDto finishAndRaw = remoteMaterialService.getFinishAndRaw(goodsCostAdjustment.getMaterialCode());
            if (finishAndRaw != null) {
                //辅助属性
                List<SysAuxiliary> statsArray = CacheUtils.get(CacheNames.SYS_GINSENG + "_" + finishAndRaw.getTenantId(), String.valueOf(finishAndRaw.getMaterialId()));
                //单位
                MaterialUnitDto unit;
                if (finishAndRaw.getMaterialUnit() != null) {
                    unit = remoteUnitService.getUnitDataByCode(Long.parseLong(finishAndRaw.getMaterialUnit())).getData();
                } else {
                    unit = remoteUnitService.getUnitDataByCode(Long.parseLong(finishAndRaw.getMaterialMoreUnit())).getData();
                }
                costAdjustmentDto
                    .setId(goodsCostAdjustment.getId())
                    .setMaterialCode(goodsCostAdjustment.getMaterialCode())
                    .setMaterialName(finishAndRaw.getMaterialName())
                    .setMaterialCategory(finishAndRaw.getMaterialCategory())
                    .setMaterialSpace(finishAndRaw.getMaterialSpace())
                    .setAuxiliaryAttribute(statsArray)
                    .setMaterialPlace(finishAndRaw.getMaterialPlace())
                    .setUnitDict(unit.getUnitName())
                    .setAdjustmentAmount(goodsCostAdjustment.getAdjustmentAmount())
                    .setRemark(goodsCostAdjustment.getRemark())
                    .setWarehouse(goodsCostAdjustment.getWarehouse())
                    .setWarehouseDict(remoteWarehouseNameService.getWarehouseName(goodsCostAdjustment.getWarehouse()));
                result.add(costAdjustmentDto);
            }
            goodsCostAdjustmentViewDto.setAddList(result);
            return goodsCostAdjustmentViewDto;
        } else {
            //单据调整
            goodsCostAdjustmentViewDto.setAdjustmentMode("单据调整");
            goodsCostAdjustmentViewDto.setAdjustmentModeNum("2");
            //根据单据号获取完工入库单相关信息
            WipCompletionMessageDto wipCompletionMessage = remoteWipService.getWipCompletionMessage(goodsCostAdjustment.getDocumentNumber());
            if (wipCompletionMessage != null) {
                //辅助属性
                List<SysAuxiliary> statsArray = CacheUtils.get(CacheNames.SYS_GINSENG + "_" + wipCompletionMessage.getTenantId(), String.valueOf(wipCompletionMessage.getMaterialId()));
                //单位
                MaterialUnitDto unit = remoteUnitService.getUnitDataByCode(Long.parseLong(wipCompletionMessage.getMaterialUnit())).getData();

                costAdjustmentDto
                    .setDocumentNumber(goodsCostAdjustment.getDocumentNumber())
                    .setDocumentType(wipCompletionMessage.getDocumentType())
                    .setMaterialCode(goodsCostAdjustment.getMaterialCode())
                    .setMaterialName(wipCompletionMessage.getMaterialName())
                    .setMaterialCategory(wipCompletionMessage.getMaterialCategory())
                    .setMaterialSpace(wipCompletionMessage.getMaterialSpace())
                    .setAuxiliaryAttribute(statsArray)
                    .setMaterialPlace(wipCompletionMessage.getMaterialPlace())
                    .setUnitDict(unit.getUnitName())
                    .setAdjustmentAmount(goodsCostAdjustment.getAdjustmentAmount())
                    .setRemark(goodsCostAdjustment.getRemark())
                    .setWarehouse(goodsCostAdjustment.getWarehouse())
                    .setWarehouseDict(remoteWarehouseNameService.getWarehouseName(goodsCostAdjustment.getWarehouse()));
                result.add(costAdjustmentDto);
            }
            goodsCostAdjustmentViewDto.setAddList(result);
            goodsCostAdjustmentViewDto.setOutRemark(goodsCostAdjustment.getOutRemark());
            return goodsCostAdjustmentViewDto;
        }
    }

    /**
     * 删除
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteGoodsCostAdjustment(Long id) {
        GoodsCostAdjustment goodsCostAdjustment = goodsCostAdjustmentMapper.selectById(id);
        if (goodsCostAdjustment.getStatus() != 1 && goodsCostAdjustment.getStatus() != 6) {
            throw new GlobalException("只能删除待提交或已关结的单据");
        }
        return goodsCostAdjustmentMapper.deleteById(goodsCostAdjustment) > 0;
    }

    /**
     * 提交审核
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean subReview(Long id) {
        GoodsCostAdjustment goodsCostAdjustment = goodsCostAdjustmentMapper.selectById(id);
        if (goodsCostAdjustment.getStatus() != 1) {
            throw new GlobalException("只能操作待提交的单据");
        }
        goodsCostAdjustment.setStatus(2);
        return goodsCostAdjustmentMapper.updateById(goodsCostAdjustment) > 0;
    }

    /**
     * 撤销审核
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteReview(Long id) {
        GoodsCostAdjustment goodsCostAdjustment = goodsCostAdjustmentMapper.selectById(id);
        if (goodsCostAdjustment.getStatus() != 2) {
            throw new GlobalException("只能操作待审核的单据");
        }
        goodsCostAdjustment.setStatus(1);
        return goodsCostAdjustmentMapper.updateById(goodsCostAdjustment) > 0;
    }

    /**
     * 审核
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean examine(ExamineVo examineVo) throws Exception {
        GoodsCostAdjustment goodsCostAdjustment = goodsCostAdjustmentMapper.selectById(examineVo.getId());
        if (goodsCostAdjustment.getStatus() != 2 && goodsCostAdjustment.getStatus() != 3) {
            throw new GlobalException("该单据不能进行审核操作");
        }
        String perms = "finance:adjustment:examine";
        //获取菜单id
        int isAdopt = examineVo.getAgreeOrNot();
        String auditDoc = goodsCostAdjustment.getId().toString();
        String auditRemarks = examineVo.getAuditOpinion();
        Long userId = LoginHelper.getUserId();
        SysAuditHistoryVo sysAuditHistoryVo = new SysAuditHistoryVo();
        sysAuditHistoryVo.setPerms(perms);
        sysAuditHistoryVo.setAuditType(15);
        sysAuditHistoryVo.setAuditState(isAdopt);
        sysAuditHistoryVo.setAuditRemarks(auditRemarks);
        sysAuditHistoryVo.setAuditDoc(auditDoc);
        sysAuditHistoryVo.setUserId(userId);
        int data = remoteReviewService.getSequence(sysAuditHistoryVo);
        //1:通过，2：审核中，3：没权限 4:该人已经审核过
        if (examineVo.getAgreeOrNot() == 1) {
            if (data == 1) {
                goodsCostAdjustment.setStatus(5);
                if ("1".equals(goodsCostAdjustment.getAdjustmentMode())) {
                    // TODO 物料调整
                } else {
                    //单据调整（审核同意之后根据单据号修改完工入库对应的单价）
                    UpdateWipByAdjustmentVo updateWipByAdjustmentVo = new UpdateWipByAdjustmentVo();
                    updateWipByAdjustmentVo.setDocumentNumber(goodsCostAdjustment.getDocumentNumber());
                    updateWipByAdjustmentVo.setWarehouse(goodsCostAdjustment.getWarehouse());
                    updateWipByAdjustmentVo.setUnitPrice(goodsCostAdjustment.getAdjustmentAmount());
                    remoteWipService.updateWipByAdjustment(updateWipByAdjustmentVo);
                }
                return goodsCostAdjustmentMapper.updateById(goodsCostAdjustment) > 0;
            } else if (data == 2) {
                goodsCostAdjustment.setStatus(3);
                return goodsCostAdjustmentMapper.updateById(goodsCostAdjustment) > 0;
            } else if (data == 3) {
                throw new GlobalException("没有审核权限");
            } else {
                throw new GlobalException("该用户已经审核过");
            }
        } else {
            if (data == 1 || data == 2) {
                goodsCostAdjustment.setStatus(4);
                return goodsCostAdjustmentMapper.updateById(goodsCostAdjustment) > 0;
            } else if (data == 3) {
                throw new GlobalException("没有审核权限");
            } else {
                throw new GlobalException("该用户已经审核过");
            }
        }
    }


}
